<template>
  <div class="wrap-area" id="form-widget">
    <!-- 入口文件 -->
    <VFormRender
      :form-json="formJson"
      :form-data="formData"
      :parent-api="parentApi"
      :option-data="optionData"
      ref="vFormRef"
    />
    <!-- 弹窗配置 -->
    <component
      v-if="layerNameKey != null"
      :is="layerNameKey"
      :visible="hasCallShow"
      :info="msgWinData"
    />

    <template v-if="false">
      <Popup
        v-model="show"
        position="top"
        :get-container="getContainer"
        overlay-class="popup-class"
      >
        <div class="content" :style="{ 'font-size': '40px' }">
          豫章故郡，洪都新府。星分翼轸，地接衡庐。襟三江而带五湖，控蛮荆而引瓯越。物华天宝，龙光射牛斗之墟；人杰地灵，徐孺下陈蕃之榻。雄州雾列，俊采星驰。台隍枕夷夏之交，宾主尽东南之美。都督阎公之雅望，棨戟遥临；宇文新州之懿范，襜帷暂驻。十旬休假，胜友如云；千里逢迎，高朋满座。腾蛟起凤，孟学士之词宗；紫电青霜，王将军之武库。家君作宰，路出名区；童子何知，躬逢胜饯。
        </div>
      </Popup>
    </template>
  </div>
</template>

<script>
import VFormRender from "@c/public/form-render/index.vue";
import { setRem2 } from "@/utils/rem.js";
import { AndroidSDK } from "@/sdk/AndroidSdkService";
import { RoomCommonObserverBiz } from "@/utils/biz/room/RoomCommonObserverBiz";
import { resetLongToStr } from "@/utils/biz/common/BizUtils";
import { SubjectUtil } from "@/utils/observer/SubjectUtil";
import { SetDateObserverBiz } from "@/utils/biz/common/SetDateObserverBiz";
import LayerComps from "@/components/public/layer/scenes";
import { RoomOverObserverBiz } from "@/utils/biz/room/RoomOverObserverBiz";
import { UserCommitApi } from "@/api/user_common";
import { Popup } from "vant";

export default {
  name: "RoomScreen",

  props: {
    formJson: {
      widgetList: [],
      formConfig: {
        devType: true,
      },
    },
    formConfig: {},
    formData: Object,
    templateInfo: {},
    // 0表示门诊 1 第三方 2 其他
    apiType: {
      type: Number,
      default: 0,
    },
    optionData: {},
  },

  components: {
    Popup,
    VFormRender,
    ...LayerComps,
  },

  data() {
    return {
      show: true,
      parentApi: this.createParentOptions(),
      deviceInfo: null,
      // 诊室屏信息缓存
      roomScreenData: {
        // 顶部科室 诊室信息
        roomDeptInfo: {
          // 科室名称
          deptName: "",
          // 科室简称
          deptShortName: "",
          // 屏幕所属科室
          oldDeptName: "",
          oldDeptShortName: "",
          // 科室简介
          deptIntroduction: "",
          // 诊室名称
          roomName: "",
          // 诊室号
          roomNo: "",
          // 诊室简称
          roomShortName: "",
        },
        //候诊类型--1候诊等候--2候诊列表
        waitPatientType: 1,
        //候诊列表截取的人数
        waitNum: 0,
        // 1 医生:顺序优先(先登录先上屏) 2 医生:时间优先(后登录后上屏)
        doctorOrder: 1,
        // 置空专用
        workerInfo: {
          workerId: "", // 医生ID
          workStationId: "", // 医生工作站ID
          registerObjIdList: [],
          workerName: "", // 医生姓名
          workerPicture: "", // 医生照片
          workerBusinessCard: "", // 医生二维码
          workerTitle: "", //医生职称
          workerIntro: "", //医生简介
          workerDegree: "", // 学历
          workerSpecialty: "", // 医生擅长
          isPause: false, // 暂停接诊状态
          onlineStatus: "2",
          deptName: "", // 医生所属科室
          preTreatingPatient: [], // 上一个正在就诊
          treatingPatient: [], //正在就诊患者
          waitingPatientList: [], // 等候就诊患者
          weekInfo: [],
          // 原始数据
          scheduleList: [],
          sortNumber: 0,
        },
        // 医生ID
        workerIdList: [],
        // 医生信息
        workerInfoList: [
          {
            workerId: "", // 医生ID
            workStationId: "", // 医生工作站ID
            registerObjIdList: [],
            workerName: "", // 医生姓名
            workerPicture: "", // 医生照片
            workerBusinessCard: "", // 医生二维码
            workerTitle: "", //医生职称
            workerIntro: "", //医生简介
            workerDegree: "", // 学历
            workerSpecialty: "", // 医生擅长
            isPause: false, // 暂停接诊状态
            onlineStatus: "2",
            deptName: "", // 医生所属科室
            preTreatingPatient: [], // 上一个正在就诊
            treatingPatient: [], //正在就诊患者
            waitingPatientList: [], // 等候就诊患者
            weekInfo: [],
            // 原始数据
            scheduleList: [],
            sortNumber: 0,
          },
        ],
        // 排班信息
        weekInfo: [
          { label: "排班", value: 0, status: "午别" },
          { label: "周一", value: 1, status: false },
          { label: "周二", value: 2, status: true },
          { label: "周三", value: 3, status: false },
          { label: "周四", value: 4, status: true },
          { label: "周五", value: 5, status: false },
          { label: "周六", value: 6, status: false },
          { label: "周日", value: 7, status: true },
        ],
      },
      // 组件缓存
      modelMap: {},
      // 缓存
      commonJsonMap: {},
      hasCallShow: false,
      // 诊室屏 -- 弹窗
      msgWinData: {
        treatingAlert: true, // 是否显示就诊弹窗
        waitingAlert: true, // 是否显示候诊弹窗
        currPatient: [],
        waitPatient: [],
        // 号别显示名称
        registerObjNameKey: "registerObjName",
        // 原始数据
        data: {},
        current: {
          content: "就诊",
        },
        waiting: {
          content: "候诊",
        },
        popupBackground: "",
        overlayBackground: "",
      },
      // 医生排班 name:'',
      workerSchedulingJson: {},
      eventBus: null,
      // 弹窗设置
      layerNameKey: "room-call-patient",
      // 暂停接诊
      pauseLayerInfo: {
        visible: false,
        info: {
          content: "暂停服务",
          fontSize: 388,
          color: "#ffffff",
          fontWeight: 500,
        },
      },
    };
  },

  computed: {
    getContainer() {
      return document.querySelector("#form-widget");
    },
  },

  mounted() {
    this.setRem();
    // 初始化
    this.init();
  },

  methods: {
    // 安卓报错信息的写入
    handleException(funcName, errType, errMsg) {
      AndroidSDK.writeLog(`${funcName}--${errType}-->${errMsg}`);
    },

    // 安卓正常写入日志
    handleWriteLog(funcName, msgContent) {
      AndroidSDK.writeLog(`${funcName}---->${msgContent}`);
    },

    /**
     * 安卓调用
     * @param obj
     */
    sdkServices(obj) {
      this.handleWriteLog("sdkServices", JSON.stringify(obj));
      try {
        if (obj.bizType && obj.bizType !== "") {
          switch (obj.bizType) {
            case "getDeviceInfoCallBack":
             
              this.deviceInfo = JSON.parse(resetLongToStr(obj.msgContent));
              this.initAfterGetDeviceInfo();
              break;
            case "webPing":
              AndroidSDK.androidPong();
              break;
            case "setDate":
              this.setDate(obj.msgContent);
              this.eventBus.$emit(obj.bizType, obj.msgContent);
              break;
            default:
              // 监听设置
              this.eventBus.$emit(obj.bizType, obj.msgContent);
          }
        } else {
          this.handleException("sdkServices", "数据错误", JSON.stringify(obj));
        }
      } catch (e) {
        this.handleException("sdkServices", "解析错误", JSON.stringify(obj));
      }
    },

    /**
     * 安卓调用
     * @param obj
     */
    sdkBizServices(obj) {
      this.handleWriteLog("sdkBizServices", JSON.stringify(obj));
      try {
        if (obj.bizType && obj.bizType !== "") {
          this.eventBus.$emit(obj.bizType, obj.msgContent);
        } else {
          this.handleException(
            "sdkBizServices",
            "数据错误",
            JSON.stringify(obj)
          );
        }
      } catch (e) {
        this.handleException("sdkBizServices", "解析错误", JSON.stringify(obj));
      }
    },

    /**
     * 初始化逻辑
     */
    init() {
      // 数据挂载
      parent.window.webSDKServices = this.sdkServices;
      parent.window.webSDKBizServices = this.sdkBizServices;
      AndroidSDK.androidPong();
      // 遍历数据 将模板数据存储到Map缓存中
      this.formJson.widgetList.forEach((item) => {
        this.modelMap[item.categoryType] = item;
      });
      // 设置接口中需要用的参数
      this.setParams();
      // 主题消息 Subject
      this.eventBus = new SubjectUtil();

      //获取终端信息
      AndroidSDK.getDeviceInfo();
    },
    /**
     * 初始化 模板参数
     */
    setParams() {
      // 加载主屏逻辑
      let mainInfo = this.modelMap["room-DRC"];
      if (mainInfo) {
        let configObj = mainInfo.options[mainInfo.options.config];
        // 医生:顺序优先(先登录先上屏) 2 医生:时间优先(后登录后上屏)
        this.roomScreenData.doctorOrder = configObj.doctorOrder || 1;
        //候诊类型--1 候诊等候--2 候诊列表  默认1
        this.roomScreenData.waitPatientType = configObj?.waitPatientType || 1;
        //候诊列表截取的人数 为0 表示不查询 默认0 即使开启了候诊列表，这个之为0 也默认走等候逻辑
        this.roomScreenData.waitNum = configObj.waitPatientNumber || 0;
        // 等候隐藏，参数置为默认值
        if (true === configObj.waitingPatientHide) {
          // 请求方式设置为候诊
          this.roomScreenData.waitPatientType = 1;
          // 等候人数为0
          this.roomScreenData.waitNum = 0;
        }

        // 模板中配置的号别KEY
        this.msgWinData.registerObjNameKey =
          configObj.registerObjNameKey || "registerObjName";

        // 设置弹窗名称
        if (configObj.layerInfo && configObj.layerInfo.current) {
          this.msgWinData.current = configObj.layerInfo.current || {
            content: "就诊",
          };
          // 颜色
          this.msgWinData.popupBackground =
            configObj.layerInfo.current.popupBackground || "";
          // 透明度
          this.msgWinData.overlayBackground =
            configObj.layerInfo.current.overlayBackground || "";
        }
        if (configObj.layerInfo && configObj.layerInfo.waiting) {
          this.msgWinData.waiting = configObj.layerInfo.waiting || {
            content: "候诊",
          };
        }

        // 调用哪个弹窗
        this.layerNameKey = configObj.layerNameKey || "room-call-patient";
        // 特制消息标识
        this.msgRegisterMark = configObj.msgRegisterMark || "";
      }
    },
    /**
     * 获取设备信息后初始化
     */
    initAfterGetDeviceInfo() {
      // 特制消息清理+注册
      this.registerMsg();

      // 加载主屏逻辑
      let mainInfo = this.modelMap["room-DRC"];
      if (mainInfo) {
        let emp = new RoomCommonObserverBiz(this, this.deviceInfo, mainInfo);
        this.eventBus.addObserver(emp);
        emp.init();
        console.log(mainInfo);

        if (mainInfo.screenDataType.indexOf("trends") === -1) {
          this.roomScreenData.workerInfoList.push(
            JSON.parse(JSON.stringify(this.roomScreenData.workerInfo))
          );
        }
      }

      // 头部时间
      if (this.modelMap["header"]) {
        // 头部时间 - 观察者
        let emp = new SetDateObserverBiz(
          this,
          this.deviceInfo,
          this.modelMap["header"]
        );
        this.eventBus.addObserver(emp);
      }

      // 内置配置
      if (this.modelMap["room-DRC"]) {
        let tempData = this.modelMap["room-DRC"];
        // 内置过号
        if (true === tempData.options[tempData.options.config].passPatient) {
          // 过号 - 观察者
          let emp = new RoomOverObserverBiz(this, this.deviceInfo, tempData);
          this.eventBus.addObserver(emp);
          emp.getPassData();
        }
      }

      // 通用过号组件
      if (this.modelMap["pass-patient-common"]) {
        let tempData = this.modelMap["pass-patient-common"];
        // 过号 - 观察者
        let emp = new RoomOverObserverBiz(this, this.deviceInfo, tempData);
        this.eventBus.addObserver(emp);
        emp.getPassData();
      }

      // 获取多媒体
      this.getVideoMedias();
    },

    /**
     * 消息注册
     */
    async registerMsg() {
      // 特制消息存在才会注册
      try {
        // 注册消息
        const { code, data } = await UserCommitApi.bindTerminalBusinessFlag({
          terminalId: this.deviceInfo.screenId,
          terminalType: this.deviceInfo.screenType,
          businessFlag: this.msgRegisterMark,
        });
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "特制消息注册失败 -- registerMsg -- >",
          JSON.stringify(e.stack)
        );
      }
    },

    /**
     * 适配2k 4k
     */
    setRem() {
      const { resolution } = this.templateInfo;
      if (resolution) {
        // 重新计算尺寸
        setRem2(19.2, resolution.split("*")[0]);
        window.onresize = function () {
          setRem2(19.2, resolution.split("*")[0]);
        };
      }
    },
    createParentOptions() {
      return {
        self: this,
        executeParentMethod(key, data) {
          switch (key) {
            case "writeLog":
              // 内部组件调用 诙谐LOG 日志
              this.self.handleWriteLog(
                "sdkBizServices",
                "内部组件打印日志 -- >",
                data || ""
              );
              break;
            case "playVideoMedias":
              // 获取视频组件位置 给安卓
              this.self.playVideoMedias(data);
              break;
          }
        },
      };
    },
    /**
     * 获取多媒体
     * @param data
     */
    getVideoMedias(data) {
      try {
        let roomItem = this.modelMap["room-DRC"];
        const formRef = this.$refs.vFormRef;
        if (formRef) {
          this.$refs.vFormRef.executeChildMethod(
            roomItem?.id,
            "getVideoMedias",
            data || {}
          );
        }
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "内部组件异常 -- getVideoMedias -- >",
          JSON.stringify(e.stack)
        );
      }
    },
    setDate(obj) {
      // 头部时间 - 观察者
      let empTime = new SetDateObserverBiz(
        this,
        this.deviceInfo,
        this.modelMap["room-DRC"]
      );
      this.eventBus.addObserver(empTime);
      try {
        let roomItem = this.modelMap["room-DRC"];
        const formRef = this.$refs.vFormRef;
        if (formRef) {
          this.$refs.vFormRef.executeChildMethod(roomItem?.id, "setDate", obj);
        }
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "内部组件异常 -- getVideoMedias -- >",
          JSON.stringify(e.stack)
        );
      }
    },

    /**
     * 获取 多媒体
     * @param obj
     */
    playVideoMedias(obj) {
      try {
        // resources:[{url: ''}]
        const { positionInfo, video } = obj;
        const { left, top, width, height } = positionInfo;
        const resources = [];
        video.forEach((item) => {
          resources.push({
            url: item.url,
          });
        });
        AndroidSDK.playVideoMedias({
          x: left,
          y: top,
          width: width,
          height: height,
          type: "2",
          resources,
        });
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "获取多媒体数据解析失败",
          JSON.stringify(e.stack)
        );
      }
    },
  },
};
</script>

<style lang="scss">
.wrap-area {
  width: 100%;
  height: 100%;
}
</style>
